package org.light.easyuilayouts.widgets;

import java.util.ArrayList;
import java.util.Set;
import java.util.TreeSet;

import org.light.core.CombSerialComparator;
import org.light.core.LayoutComb;
import org.light.core.ManyToManySerialComparator;
import org.light.core.ReportComb;
import org.light.core.Widget;
import org.light.domain.Domain;
import org.light.domain.DomainSerialComparator;
import org.light.domain.ManyToMany;
import org.light.domain.MenuItem;
import org.light.domain.MenuItemSerialComparator;
import org.light.domain.Statement;
import org.light.domain.StatementList;
import org.light.exception.ValidateException;
import org.light.utils.DomainUtil;

public class Nav extends Widget{
	protected Set<Domain> domains = new TreeSet<>(new  DomainSerialComparator());
	protected MenuItem profileMenu;
	protected Set<ManyToMany> mtms = new TreeSet<>(new  ManyToManySerialComparator());
	protected Set<LayoutComb> layouts = new TreeSet<>(new  CombSerialComparator());
	protected Set<ReportComb> reports = new TreeSet<>(new  CombSerialComparator());
	protected Set<MenuItem> menus = new TreeSet<>();
	protected String language = "Chinese";
	
	public MenuItem getProfileMenu() {
		return profileMenu;
	}

	public void setProfileMenu(MenuItem profileMenu) {
		this.profileMenu = profileMenu;
	}

	@Override
	public StatementList generateWidgetStatements() throws ValidateException{
		StatementList sList = new StatementList();
		
		sList.add(new Statement(1000L,0,"<div onclick=\"window.location='../pages/index.html'\" class=\"menu-item\" style=\"height: 20px;\"><div class=\"menu-text\" style=\"height: 20px; line-height: 20px;\">主页</div><div class=\"menu-icon icon-add\"></div></div>"));
		long serial = 2000L;
		Set<MenuItem> tempmenus = this.getNavMenuItems();
		for (MenuItem mi : tempmenus){
			sList.add(new Statement(serial,0,"<div onclick=\"window.location='"+mi.getUrl()+"'\" class=\"menu-item\" style=\"height: 20px;\"><div class=\"menu-text\" style=\"height: 20px; line-height: 20px;\">"+mi.getText()+"</div><div class=\"menu-icon icon-add\"></div></div>"));
			serial += 1000L;
		}
		sList.setSerial(this.serial);
		return sList;
	} 
	
	public StatementList generateEnglishWidgetStatements() throws ValidateException{
		StatementList sList = new StatementList();
		
		sList.add(new Statement(1000L,0,"<div onclick=\"window.location='../pages/index.html'\" class=\"menu-item\" style=\"height: 20px;\"><div class=\"menu-text\" style=\"height: 20px; line-height: 20px;\">Homepage</div><div class=\"menu-icon icon-add\"></div></div>"));
		long serial = 2000L;
		Set<MenuItem> tempmenus = this.getNavMenuItems();
		for (MenuItem mi : tempmenus){
			sList.add(new Statement(serial,0,"<div onclick=\"window.location='"+mi.getUrl()+"'\" class=\"menu-item\" style=\"height: 20px;\"><div class=\"menu-text\" style=\"height: 20px; line-height: 20px;\">"+mi.getText()+"</div><div class=\"menu-icon icon-add\"></div></div>"));
			serial += 1000L;
		}
		sList.setSerial(this.serial);
		return sList;
	} 

	@Override
	public StatementList generateWidgetScriptStatements() {
		Statement s = new Statement();
		StatementList sl = new StatementList();
		sl.add(s);
		sl.setSerial(this.serial);
		return sl;
	}

	@Override
	public boolean parse() throws ValidateException{
		if (this.menus==null||this.menus.size()==0) {
			Long serial = 0L;
			Set<ManyToMany> mtms = new TreeSet<>(new ManyToManySerialComparator());
			if (this.domains!=null&&this.domains.size()>0) {
				for (Domain d:this.domains) {
					MenuItem mi = new MenuItem("../pages/"+d.getPlural().toLowerCase()+".html",d.getStandardName(),d.getText());
					mi.setSerial(serial);
					serial += 1000L;
					menus.add(mi);
				}
				long serial2 = 0L;
				for (Domain d:this.domains) {				
					Set<ManyToMany> mtmset = d.getManyToManies();
					for (ManyToMany mtm:mtmset) {
						mtm.setMaster(d);
						if (mtm.getSlave()!=null) {
							mtm.setSlave(mtm.getSlave());
						}else {
							ArrayList<Domain> targetDomains = new ArrayList<Domain>();
							targetDomains.addAll(this.domains);
							Domain slave = DomainUtil.findDomainInList(targetDomains, mtm.getManyToManySalveName());
							mtm.setSlave(slave);
						}
						mtm.setSerial(serial2);
						serial2 += 1000L;
						mtms.add(mtm);
					}
				}
			}
			if (this.profileMenu != null) {
				profileMenu.setSerial(serial);
				serial += 1000L;
				menus.add(profileMenu);
			}
			if (mtms!=null&&mtms.size()>0) {
				for (ManyToMany mtm:mtms) {
					MenuItem mi = new MenuItem("../pages/" + ("Link"+mtm.getMaster().getStandardName()+mtm.getSlaveAlias()).toLowerCase()+ ".html",
							mtm.getStandardName(), mtm.getText());
					mi.setSerial(serial);
					serial += 1000L;
					menus.add(mi);
				}				
			}
			if (this.layouts!=null&&this.layouts.size()>0) {
				for (LayoutComb layout:this.layouts) {
					MenuItem mi = new MenuItem("../pages/" + layout.getStandardName().toLowerCase() + ".html",
							layout.getStandardName(), layout.getText());
					mi.setSerial(serial);
					serial += 1000L;
					this.menus.add(mi);
				}				
			}
			if (this.reports!=null&&this.reports.size()>0) {
				for (ReportComb report:this.reports) {
					MenuItem mi = new MenuItem("../pages/" + report.getStandardName().toLowerCase() + ".html",
							report.getStandardName(), report.getText());
					mi.setSerial(serial);
					serial += 1000L;
					this.menus.add(mi);
				}				
			}
		}
		return true;
	}

	public Set<Domain> getDomains() {
		return domains;
	}

	public void setDomains(Set<Domain> domains) {
		this.domains = domains;
	}

	public Set<ManyToMany> getMtms() {
		return mtms;
	}

	public void setMtms(Set<ManyToMany> mtms) {
		this.mtms = mtms;
	}

	public Set<MenuItem> getMenus() {
		return menus;
	}

	public void setMenus(Set<MenuItem> menus) {
		this.menus = menus;
	}

	public Set<LayoutComb> getLayouts() {
		return layouts;
	}

	public void setLayouts(Set<LayoutComb> layouts) {
		this.layouts = layouts;
	}
	
	public void addLayout(LayoutComb layout) {
		Long maxserial = 0L;
		for (LayoutComb l:this.layouts) {
			if (l.getSerial()>maxserial) {
				maxserial = l.getSerial();
			}
		}
		maxserial += 1000l;
		layout.setSerial(maxserial);
		this.layouts.add(layout);
	}

	public Set<ReportComb> getReports() {
		return reports;
	}

	public void setReports(Set<ReportComb> reports) {
		this.reports = reports;
	}
	public void addReport(ReportComb report) {
		Long maxserial = 0L;
		for (ReportComb r:this.reports) {
			if (r.getSerial()>maxserial) {
				maxserial = r.getSerial();
			}
		}
		maxserial += 1000l;
		report.setSerial(maxserial);
		this.reports.add(report);
	}
	
	public Set<MenuItem> getNavMenuItems() throws ValidateException{
		Set<MenuItem> menus = new TreeSet<>(new MenuItemSerialComparator());
		Set<ManyToMany> mtms = new TreeSet<>(new ManyToManySerialComparator());
		long serial = 0L;
		if (this.domains!=null&&this.domains.size()>0) {
			for (Domain d:this.domains) {
				MenuItem mi = new MenuItem("../pages/"+d.getPlural().toLowerCase()+".html",d.getStandardName(),d.getText());
				mi.setSerial(serial);
				serial += 1000L;
				menus.add(mi);
			}
		}
		if (this.profileMenu != null) {
			profileMenu.setSerial(serial);
			serial += 1000L;
			menus.add(profileMenu);
		}
		if (this.mtms!=null&& this.mtms.size()>0) {
			for (ManyToMany mtm:this.mtms) {
				MenuItem mi = new MenuItem("../pages/" + ("Link"+mtm.getMaster().getStandardName()+mtm.getSlaveAlias()).toLowerCase()+ ".html",
						mtm.getStandardName(), mtm.getText());
				mi.setSerial(serial);
				serial += 1000L;
				menus.add(mi);
			}				
		}
		if (this.layouts!=null&&this.layouts.size()>0) {
			for (LayoutComb layout:this.layouts) {
				MenuItem mi = new MenuItem("../pages/" + layout.getStandardName().toLowerCase() + ".html",
						layout.getStandardName(), layout.getText());
				mi.setSerial(serial);
				serial += 1000L;
				menus.add(mi);
			}				
		}
		if (this.reports!=null&&this.reports.size()>0) {
			for (ReportComb report:this.reports) {
				MenuItem mi = new MenuItem("../pages/" + report.getStandardName().toLowerCase() + ".html",
						report.getStandardName(), report.getText());
				mi.setSerial(serial);
				serial += 1000L;
				menus.add(mi);
			}				
		}
		return menus;
	}

	public String getLanguage() {
		return language;
	}

	public void setLanguage(String language) {
		this.language = language;
	}
} 
